#include "singleapplication.h"
#include <QtNetwork/QLocalSocket>
#include <QFileInfo>

#define TIME_OUT                (500)    // 500ms

#define ENV_ESYNC_DATA_DIR		"ESYNC_DATA_DIR"
#define OTA_EVENTS_DIR			"misc/ota_events"
#define HMI_PIPE_TYPE			"engine_running"

#ifndef LEN_MAX
# define LEN_MAX 256
#endif

SingleApplication::SingleApplication(int argc, char **argv)
    : QApplication(argc, argv)
    , w(NULL)
    , _isRunning(false)
    , _localServer(NULL)
{
    _serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName();
    if (argc == 2)
        _serverName.append(argv[1]);
    _initLocalConnection();
}

bool SingleApplication::isRunning()
{
    return _isRunning;
}

void SingleApplication::_newLocalConnection()
{
    QLocalSocket *socket = _localServer->nextPendingConnection();
    if (socket) {
        socket->waitForReadyRead(2 * TIME_OUT);
        delete socket;
        _activateWindow();
    }
}

#define _VERIFY(st) if(!(st)) { qDebug("Action failed\n"); exit(1); }

//----------------------------------------------------------------------------------
#ifdef Q_OS_LINUX
void tst_QTcpSocket::linuxKernelBugLocalSocket()
{
	char *esync_data = getenv(ENV_ESYNC_DATA_DIR);
	char fifo[LEN_MAX] = {0};

	if (snprintf(fifo, sizeof(fifo) - 1, "%s/%s/%s", esync_data, OTA_EVENTS_DIR, HMI_PIPE_TYPE) < 0) {
		qDebug ("Failed to get hmi path: %s\n", fifo);
		return -1;
	}

    QFile fileReader(fifo);
	// wait for connect
	while (!fileReader.open(QFile::ReadOnly)) {
		usleep(TIME_OUT);
	}

    //_VERIFY(fileReader.open(QFile::ReadOnly));
	QLocalSocket socket;
    //QTcpSocket *socket = newSocket();
    socket->setSocketDescriptor(fileReader.handle());

	_isRunning = true;
	return;

    //_VERIFY(socket->waitForReadyRead(5000));
    //socket->bytesAvailable();
    //QCOMPARE(socket->bytesAvailable(), qint64(128));

    //QFile::remove("fifo");
    //delete socket;
}
#endif

void SingleApplication::_initLocalConnection()
{
    _isRunning = false;    

	
    QLocalSocket socket;
    socket.connectToServer(_serverName);
    if (socket.waitForConnected(TIME_OUT)) {
        _isRunning = true;
        return;
    }

    _newLocalServer();
}

void SingleApplication::_newLocalServer()
{
    _localServer = new QLocalServer(this);
    connect(_localServer, SIGNAL(newConnection()), this, SLOT(_newLocalConnection()));
    if (!_localServer->listen(_serverName)) {
        if (_localServer->serverError() == QAbstractSocket::AddressInUseError) {
            QLocalServer::removeServer(_serverName);
            _localServer->listen(_serverName);
        }
    }
}

void SingleApplication::_activateWindow()
{
    if (w) {
        w->showNormal();
        w->activateWindow();
    }
}
